package settings

import (
	"fmt"
	"log"
	"time"

	"github.com/go-ini/ini"
	_ "github.com/go-sql-driver/mysql"
	"github.com/go-xorm/core"
	"github.com/go-xorm/xorm"
)

//
//var (
//	Cfg     *ini.File
//	RunMode string
//
//	HttpPort     int
//	ReadTimeOut  time.Duration
//	WriteTimeOut time.Duration
//
//	PageSize  int
//	JwtSecret string
//
//	dns       string
//)

var MasterDB *xorm.Engine

type App struct {
	JwtSecret       string
	PageSize        int
	RuntimeRootPath string

	ImagePrefixUrl string
	ImageSavePath  string
	ImageMaxSize   int
	ImageAllowExts []string

	LogSavePath string
	LogSaveName string
	LogFileExt  string
	TimeFormat  string
}

var AppSetting = &App{}

type Server struct {
	RunMode      string
	HttpPort     int
	ReadTimeOut  time.Duration
	WriteTimeOut time.Duration
}

var ServerSetting = &Server{}

type MysqlInfo struct {
	Type        string
	User        string
	Password    string
	Host        string
	DbName      string
	TablePrefix string
	MaxIdle     int
	MaxCon      int
	Show        bool
	Level       int
}

var MysqlbaseSetting = &MysqlInfo{}

func SetUp(path string) {
	//path := "src/job/conf/app.ini"

	Cfg, err := ini.Load(path)
	if err != nil {
		log.Fatalf("Fail to parse '%s': %v", path, err)
	}

	err = Cfg.Section("app").MapTo(AppSetting)
	if err != nil {
		log.Fatalf("Cfg.MapTo AppSetting err: %v", err)
	}

	AppSetting.ImageMaxSize = AppSetting.ImageMaxSize * 1024 * 1024

	err = Cfg.Section("server").MapTo(ServerSetting)
	if err != nil {
		log.Fatalf("Cfg.MapTo ServerSetting err: %v", err)
	}

	ServerSetting.ReadTimeOut = ServerSetting.ReadTimeOut * time.Second
	ServerSetting.WriteTimeOut = ServerSetting.ReadTimeOut * time.Second

	err = Cfg.Section("mysql").MapTo(MysqlbaseSetting)
	if err != nil {
		log.Fatalf("Cfg.MapTo DatabaseSetting err: %v", err)
	}

	fillDns()
}

//func ReloadConfigFile(configPath string) {
//	var err error
//	Cfg, err = ini.Load(configPath)
//	if err != nil {
//		fmt.Println("reload config file, error:", err)
//		return
//	}
//
//	fmt.Println("reload config file successfully！")
//}

//func init() {
//	var err error
//	path := "src/job/conf/app.ini"
//	Cfg, err = ini.Load(path)
//
//	if err != nil {
//		log.Fatalf("fail to parse 'conf/app.ini' : %v", err)
//	}
//	go func() {
//		ch := make(chan os.Signal, 1)
//		signal.Notify(ch, syscall.SIGHUP)
//
//		for {
//			sig := <-ch
//			switch sig {
//			case syscall.SIGSEGV:
//				ReloadConfigFile(path)
//			}
//		}
//	}()
//
//	LoadBase()
//	LoadServer()
//	LoadApp()
//	LoadMysql()
//}
//
//func LoadBase() {
//	RunMode = Cfg.Section("").Key("RUN_MODE").MustString("debug")
//}
//
//func LoadServer() {
//
//	//sec := GetSec("server")
//	RunMode = Cfg.Section("").Key("RUN_MODE").MustString("debug")
//
//	HttpPort = GetSec("server", "HTTP_PORT").MustInt(8080)
//	ReadTimeOut = time.Duration(GetSec("server", "READ_TIMEOUT").MustInt(60)) * time.Second
//	WriteTimeOut = time.Duration(GetSec("server", "WRITE_TIMEOUT").MustInt(60)) * time.Second
//}
//
//func GetSec(s, key string) *ini.Key {
//	sec, err := Cfg.GetSection(s)
//	if err != nil {
//		log.Fatalf("Fail to get section 'server' : %v", err)
//		panic(err)
//	}
//
//	value, _ := sec.GetKey(key)
//	return value
//}
//func LoadApp() {
//	//sec := GetSec("app")
//	JwtSecret = GetSec("app", "JWT_SECRET").MustString("!@)*#)!@U#@*!@!)")
//	PageSize = GetSec("app", "PAGE_SIZE").MustInt(10)
//
//}

//func LoadMysql() {
//
//	// 启动时就打开数据库连接
//	if err = initEngine(); err != nil {
//		panic(err)
//	}
//}

func fillDns() {
	dns := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=True&loc=Local",
		MysqlbaseSetting.User,
		MysqlbaseSetting.Password,
		MysqlbaseSetting.Host,
		MysqlbaseSetting.DbName)

	if err := initEngine(dns); err != nil {
		panic(err)
	}
}

func initEngine(dns string) error {
	var err error
	fmt.Println("dns", dns)
	MasterDB, err = xorm.NewEngine("mysql", dns)
	if err != nil {
		return err
	}

	maxIdle := MysqlbaseSetting.MaxIdle
	maxConn := MysqlbaseSetting.MaxCon

	MasterDB.SetMaxIdleConns(maxIdle)
	MasterDB.SetMaxOpenConns(maxConn)

	showSQL := MysqlbaseSetting.Show
	logLevel := MysqlbaseSetting.Level

	MasterDB.ShowSQL(showSQL)
	MasterDB.Logger().SetLevel(core.LogLevel(logLevel))

	// 启用缓存
	// cacher := xorm.NewLRUCacher(xorm.NewMemoryStore(), 1000)
	// MasterDB.SetDefaultCacher(cacher)

	return nil
}
